﻿/*
Plugin=QRCode
Name1=&Q   二维码
Command1=QRCode
Author=一壸浊酒、Array
Version=0.2
Date=2015/12/11
*/

; 在原来的QRCode基础上增加自动调整大小、按Esc直接复制到剪贴板的功能

QRCode()
{
    QRCode9.PNGFile := A_Temp "\二维码.png"
    If FileExist(QRCode9.PNGFile)
        FileDelete, % QRCode9.PNGFile
    QRCode9.GeneratePNG(QZData("Text"), QRCode9.PNGFile)
    QRCode9.ImgSize(QRCode9.PNGFile) ; 将宽高保存到 QRCode9.width 和 QRCode9.height
    GUI, QRCode9: Destroy
    GUI, QRCode9: Default
    GUI, QRCode9: Add, Button, x10 y10 w90 h26 gQRCode9_SaveAs,另存为(&S)
    GUI, QRCode9: Add, Text, x110 y17 h24 , 【按Esc直接复制】
    If QRCode9.Width < 200
    {
        QRCode9.width := 200
        QRCode9.height := 200
    }
    optPic := "x10 y45 w" QRCode9.width " h" QRCode9.height
    GUI, QRCode9: Add, Pic, %optPic%, % QRCode9.PNGFile
    GUI, QRCode9: Show, AutoSize Center, 二维码
}


QRCode9GUIEscape:
    WinGetPos,dx,dy, , ,二维码 ahk_class AutoHotkeyGUI
    QRCode9.CaptureScreen(dx+13, dy+70, QRCode9.width, QRCode9.height) 
    GUI,QRCode9:Destroy
Return

QRCode9_SaveAs:
    Fileselectfile,nf,s16,,另存为,PNG图片(*.png)
    If not strlen(nf)
        return
    nf := RegExMatch(nf,"i)\.png") ? nf : nf ".png"
    Filecopy,% QRCode9.PNGFile, %nf%, 1
Return


Class QRCode9
{
    Static Width
    Static Height
    Static PNGFile

    GeneratePNG(aString, sFile)
    {
        SplitPath, A_LineFile, , QRCodePath
        DllCall( QRCodePath "\quricol32.dll\GeneratePNG","str", sFile , "str", Substr(aString,1,850), "int", 2, "int", 4, "int", 0) 
    }

    CaptureScreen(nL, nT, nW, nH)
    {
        mDC := DllCall("CreateCompatibleDC", "Uint", 0)
        hBM := This.CreateDIBSection(mDC, nW, nH)
        oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
        hDC := DllCall("GetDC", "Uint", 0)
        DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
        DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
        DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
        DllCall("DeleteDC", "Uint", mDC)
        This.SetClipboardData(hBM)
    }
    
    CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "") 
    {
        NumPut(VarSetCapacity(bi, 40, 0), bi)
        NumPut(nW, bi, 4)
        NumPut(nH, bi, 8)
        NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
        NumPut(0,  bi,16)
        Return	DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
    }

    SetClipboardData(hBitmap)
    {
        DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
        hDIB :=	DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
        pDIB :=	DllCall("GlobalLock", "Uint", hDIB)	
        DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)	
        DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))	
        DllCall("GlobalUnlock", "Uint", hDIB)
        DllCall("DeleteObject", "Uint", hBitmap)
        DllCall("OpenClipboard", "Uint", 0)
        DllCall("EmptyClipboard")
        DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
        DllCall("CloseClipboard")
    }

    ImgSize(File)
    {
        static Module
        if IsObject(File) and hModule := DllCall("GetModuleHandle", "str", "gdiplus")
            Return DllCall("FreeLibrary", "uint", hModule)
        if !DllCall("GetModuleHandle","str","gdiplus")
            DllCall("LoadLibrary","str","gdiplus"),Module:={base:{__Delete: "ImgSize9"}}
        VarSetCapacity(s,16,0), NumPut(1,s)
            ,DllCall("gdiplus\GdiplusStartup","uint*",Token,"uint",&s,"uint",0)
            ,DllCall("gdiplus\GdipCreateBitmapFromFileICM", "wstr", File, "Ptr*", pBitmap )
            ,DllCall("gdiplus\GdipGetImageDimension", "Ptr", pBitmap, "Float*", width, "Float*", height )
            ,DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
            ,DllCall("gdiplus\GdiplusShutdown",ptr,Token)
        This.width := Floor(width)
        This.Height := Floor(height)
    }
}


